﻿using YDT_PaymentService.Domain.Enums;

namespace YDT_PaymentService.Domain.Entities
{
    /// <summary>
    /// 支付聚合根 - 支付是聚合根，包含支付的核心信息
    /// 聚合根：负责维护支付状态的完整性和业务规则
    /// </summary>
    public class Payment : Entity, IAggregateRoot
    {
        /// <summary>支付金额</summary>
        public decimal PaymentPrice { get; private set; }
        /// <summary>支付状态</summary>
        public PaymentStatus PaymentStatus { get; private set; }
        /// <summary>订单ID</summary>
        public Guid OrderId { get; private set; }
        /// <summary>支付类型</summary>
        public PaymentType PaymentType { get; private set; }
        /// <summary>支付方式</summary>
        public string PaymentMethod { get; private set; }
        /// <summary>支付创建时间</summary>
        public DateTime CreateTime { get; private set; }
        /// <summary>支付更新时间</summary>
        public DateTime UpdateTime { get; set; }
        /// <summary>支付备注</summary>
        public string PaymentRemark { get; private set; }
        /// <summary>支付URL - 用于前端跳转支付页面</summary>
        public string PaymentUrl { get; private set; }
        /// <summary>支付回调URL - 支付平台回调地址</summary>
        public string PaymentReturnUrl { get; private set; }
        /// <summary>支付单号 - 业务唯一标识</summary>
        public string PaymentCode { get; private set; }
        /// <summary>用户ID</summary>
        public Guid UserId { get; private set; }
        /// <summary>支付错误编号</summary>
        public string PaymentErrorNo { get; private set; }
        /// <summary>支付错误信息</summary>
        public string PaymentErrorInfo { get; private set; }
        /// <summary>支付完成时间</summary>
        public DateTime? PaymentTime { get; private set; }

        /// <summary>
        /// 受保护的构造函数 - 用于EF Core
        /// </summary>
        protected Payment() { }

        /// <summary>
        /// 创建支付构造函数
        /// </summary>
        public Payment(Guid orderId, Guid userId, decimal paymentPrice, PaymentType paymentType,
                      string paymentMethod, string paymentReturnUrl, string paymentRemark = "")
        {
            Id = Guid.NewGuid();
            OrderId = orderId;
            UserId = userId;
            PaymentPrice = paymentPrice;
            PaymentType = paymentType;
            PaymentMethod = paymentMethod;
            PaymentReturnUrl = paymentReturnUrl;
            PaymentRemark = paymentRemark;
            PaymentStatus = PaymentStatus.Pending; // 默认待支付状态
            PaymentCode = GeneratePaymentCode();
            CreateTime = DateTime.UtcNow;
            UpdateTime = DateTime.UtcNow;
            PaymentErrorNo = string.Empty;
            PaymentErrorInfo = string.Empty;
            PaymentUrl = "默认值";

            // 验证业务规则
            ValidateCreation();
        }

        /// <summary>
        /// 初始化支付（生成支付URL等）
        /// </summary>
        public void InitializePayment(string paymentUrl)
        {
            if (PaymentStatus != PaymentStatus.Pending)
                throw new InvalidOperationException("只有待支付状态的支付记录才能初始化");

            PaymentUrl = paymentUrl;
            PaymentStatus = PaymentStatus.Initialized;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 处理支付成功
        /// </summary>
        public void ProcessSuccess()
        {
            if (PaymentStatus != PaymentStatus.Initialized && PaymentStatus != PaymentStatus.Pending)
                throw new InvalidOperationException("只有已初始化或待支付状态的支付记录才能标记为成功");

            PaymentStatus = PaymentStatus.Success;
            PaymentTime = DateTime.UtcNow;
            UpdateTime = DateTime.UtcNow;

            // 清空错误信息
            PaymentErrorNo = string.Empty;
            PaymentErrorInfo = string.Empty;
        }

        /// <summary>
        /// 处理支付失败
        /// </summary>
        public void ProcessFailure(string errorNo, string errorInfo)
        {
            if (PaymentStatus != PaymentStatus.Initialized && PaymentStatus != PaymentStatus.Pending)
                throw new InvalidOperationException("只有已初始化或待支付状态的支付记录才能标记为失败");

            PaymentStatus = PaymentStatus.Failed;
            PaymentErrorNo = errorNo;
            PaymentErrorInfo = errorInfo;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 取消支付
        /// </summary>
        public void Cancel()
        {
            if (PaymentStatus != PaymentStatus.Pending && PaymentStatus != PaymentStatus.Initialized)
                throw new InvalidOperationException("只有待支付或已初始化状态的支付记录才能取消");

            PaymentStatus = PaymentStatus.Cancelled;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 处理支付退款
        /// </summary>
        public void ProcessRefund()
        {
            if (PaymentStatus != PaymentStatus.Success)
                throw new InvalidOperationException("只有支付成功的记录才能退款");

            PaymentStatus = PaymentStatus.Refunded;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 处理支付退款失败
        /// </summary>
        public void ProcessRefundFailed(string errorNo, string errorInfo)
        {
            if (PaymentStatus != PaymentStatus.Refunding)
                throw new InvalidOperationException("只有退款中的记录才能标记为退款失败");

            PaymentStatus = PaymentStatus.RefundFailed;
            PaymentErrorNo = errorNo;
            PaymentErrorInfo = errorInfo;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 开始退款流程
        /// </summary>
        public void StartRefund()
        {
            if (PaymentStatus != PaymentStatus.Success)
                throw new InvalidOperationException("只有支付成功的记录才能开始退款");

            PaymentStatus = PaymentStatus.Refunding;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 更新支付信息
        /// </summary>
        public void UpdatePaymentInfo(decimal paymentPrice, string paymentMethod, string paymentRemark = "")
        {
            if (PaymentStatus != PaymentStatus.Pending)
                throw new InvalidOperationException("只有待支付状态的支付记录才能更新信息");

            PaymentPrice = paymentPrice;
            PaymentMethod = paymentMethod;

            if (!string.IsNullOrEmpty(paymentRemark))
            {
                PaymentRemark = paymentRemark;
            }

            UpdateTime = DateTime.UtcNow;

            ValidatePaymentInfo();
        }

        /// <summary>
        /// 验证支付创建时的业务规则
        /// </summary>
        private void ValidateCreation()
        {
            if (PaymentPrice <= 0)
                throw new ArgumentException("支付金额必须大于0");

            if (string.IsNullOrWhiteSpace(PaymentMethod))
                throw new ArgumentException("支付方式不能为空");

            if (string.IsNullOrWhiteSpace(PaymentReturnUrl))
                throw new ArgumentException("支付回调URL不能为空");
        }

        /// <summary>
        /// 验证支付信息
        /// </summary>
        private void ValidatePaymentInfo()
        {
            if (PaymentPrice <= 0)
                throw new ArgumentException("支付金额必须大于0");

            if (string.IsNullOrWhiteSpace(PaymentMethod))
                throw new ArgumentException("支付方式不能为空");
        }

        /// <summary>
        /// 生成支付单号
        /// </summary>
        private static string GeneratePaymentCode()
        {
            return $"PAY{DateTime.UtcNow:yyyyMMddHHmmss}{Random.Shared.Next(1000, 9999)}";
        }
    }
}
